home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
xlib.lha
/
xlib
/
cdecl
/
extern.scm
< prev
next >
Wrap
Text File
|
1990-06-05
|
8KB
|
227 lines
;;; C declaration compiler.
;* Copyright 1989 Digital Equipment Corporation
;* All Rights Reserved
;*
;* Permission to use, copy, and modify this software and its documentation is
;* hereby granted only under the following terms and conditions. Both the
;* above copyright notice and this permission notice must appear in all copies
;* of the software, derivative works or modified versions, and any portions
;* thereof, and both notices must appear in supporting documentation.
;*
;* Users of this software agree to the terms and conditions set forth herein,
;* and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
;* right and license under any changes, enhancements or extensions made to the
;* core functions of the software, including but not limited to those affording
;* compatibility with other hardware or software environments, but excluding
;* applications which incorporate this software. Users further agree to use
;* their best efforts to return to Digital any such changes, enhancements or
;* extensions that they make and inform Digital of noteworthy uses of this
;* software. Correspondence should be provided to Digital at:
;*
;* Director of Licensing
;* Western Research Laboratory
;* Digital Equipment Corporation
;* 100 Hamilton Avenue
;* Palo Alto, California 94301
;*
;* This software may be distributed (but not offered for sale or transferred
;* for compensation) to third parties, provided such third parties agree to
;* abide by the terms and conditions of this notice.
;*
;* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
;* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
;* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
;* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
;* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
;* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
;* SOFTWARE.
;;; This module compiles "extern" forms which define C library procedures.
;;;
;;; <extern> ::= ( EXTERN <type> <fname> [ <arg> ... ] )
;;;
;;; <fname> ::= a Scheme string
;;;
;;; <arg> ::= ( <type> <id> )
;;; ( IN <type> <id> )
;;; ( OUT <type> <id> )
;;; ( IN_OUT <type> <id> )
;;;
;;; <id> ::= a Scheme symbol
(module extern)
;;; The following function syntax checks an extern expression. It will either
;;; report an error, or return the expression as its value.
(define (INPUT-EXTERN exp)
(if (and (>= (length exp) 3)
(parse-type (cadr exp))
(string? (caddr exp)))
(begin (for-each parse-arg (cdddr exp))
exp)
(error "Illegal EXTERN syntax: ~s" exp)))
;;; Parses the argument list and calls error on an error.
(define (PARSE-ARG exp)
(if (and (pair? exp)
(or (and (= (length exp) 2)
(parse-type (car exp))
(symbol? (cadr exp)))
(and (= (length exp) 3)
(memq (car exp) '(in out in_out))
(parse-type (cadr exp))
(symbol? (caddr exp)))))
#t
(error "Illegal ARGUMENT syntax: ~s" exp)))
;;; Code is generated by the following function.
(define (EMIT-EXTERNS externs extern-file-root type-file-root)
(let ((module (uis extern-file-root)))
(with-output-to-file
(string-append extern-file-root ".t")
(lambda ()
(write `(herald ,module (env tsys (xlib interface))))
(newline)
; (write `(include ,(string-append type-file-root ".sch")))
(newline)
(for-each (lambda (x) (emit-extern x 'define)) externs)))))
;;; The definition for the interface procedure for an extern is created by
;;; the following procedure.
(define (EMIT-EXTERN extern defform)
(let ((xname (uis (caddr extern) "*"))
(rettype (cadr extern))
(args (cdddr extern)))
(define (EMIT-CALL)
`(,xname ,@(map (lambda (x) (car (last-pair x))) args)))
(define (FORMALS args)
(if args
(if (eq? (caar args) 'out)
(formals (cdr args))
(cons (car (last-pair (car args)))
(formals (cdr args))))
'()))
(pp `(define-foreign ,xname
(,(caddr extern) ,@(map simple-type-arg args))
,(simple-type-return rettype)
))
(newline)
(pp `(,defform (,(uis (caddr extern)) ,@(formals args))
(let* (,@(map arg-in args)
(return-value
,(cond ((eq? rettype 'void)
`(block ,(emit-call) '#f))
((eq? rettype 'string)
`(asciz->string ,(emit-call)))
((isa-pointer? rettype)
`(cons ',(base-type rettype)
,(emit-call)))
(else (emit-call)))))
,(let ((out (args-out args)))
(if out
(if (eq? rettype 'void)
(if (= (length out) 1)
(car out)
`(return ,@out))
`(return return-value ,@out))
'return-value)))))
(newline)))
;;; Called to do input conversion for arguments. Return an expression
;;; of th form (<var> <value>).
(define (ARG-IN arg)
(let* ((flag (if (memq (car arg) '(in out in_out))
(car arg)
#f))
(type (if flag (cadr arg) (car arg)))
(var (if flag (caddr arg) (cadr arg))))
(case flag
((out) `(,var (make-bytev ,(if (eq? type 'string)
4
(size-of type)))))
(else (cond ((eq? type 'string)
`(,var (if (string? ,var)
(string->asciz! ,var)
(error
"Argument is incorrect type: ~s"
,var))))
((isa-pointer? type)
`(,var (,(uis "CHK-" (base-type type)) ,var)))
(else `(,var ,var)))))))
;;; Return a list of the expressions required to do output conversion after
;;; an external call.
(define (ARGS-OUT args)
(define (ARG-OUT arg)
(let* ((flag (if (memq (car arg) '(in out in_out))
(car arg)
#f))
(type (if flag (cadr arg) (car arg)))
(var (if flag (caddr arg) (cadr arg))))
(case flag
((out)
(cond ((eq? type 'string)
`(string->asciz! (mref-pointer ,var 0)))
((isa-pointer? type)
`(cons ',(base-type type)
(mref-pointer ,var 0)))
((or (isa-union? type) (isa-struct? type)
(isa-array? type))
`(cons ',(pointed-to-by type) ,var))
(else `(,(getprop (base-type type) 'to-get)
,var 0))))
(else #f))))
(if args
(let ((out (arg-out (car args))))
(if out
(cons out (args-out (cdr args)))
(args-out (cdr args))))
'()))
;;; Converts the type of a procedure argument to a simple C-type.
;(define returned-pointers
; '(Region charAP XVisualInfoP XImageP XrmString XrmDatabase DisplayP GC
; ScreenP VisualP AtomAP XFontStructP charPAP ColormapAP KeySymAP
; XModifierKeymapP XHostAdressAP XTimeCoordAP))
(define (SIMPLE-TYPE-arg type)
(let ((type (car type)))
(cond ((eq? type 'out) '(in rep/extend))
((eq? type 'string) '(in rep/string))
((isa-pointer? type) '(in rep/c-pointer))
((isa-procp? type) '(in rep/extend))
(else
(xcase (base-type type)
((char) '(in rep/char))
((shortint shortunsigned int unsigned) '(in rep/integer)))))))
(define (SIMPLE-TYPE-return type)
(cond ((eq? type 'void) 'ignore)
((eq? type 'string) 'rep/pointer)
((isa-pointer? type) 'rep/pointer)
((isa-procp? type) 'rep/pointer)
(else
(xcase (base-type type)
((char) 'rep/char)
((shortint shortunsigned int unsigned) 'rep/integer)))))